package com.ykt.service;

import com.jfinal.aop.Before;
import com.jfinal.aop.Enhancer;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.ykt.cache.OrderCache;
import com.ykt.common.constant.ValueConstants;
import com.ykt.common.utils.Colls;
import com.ykt.common.utils.DateUtil;
import com.ykt.common.utils.ModelUtil;
import com.ykt.common.utils.NumUtil;
import com.ykt.common.utils.UB;
import com.ykt.common.utils.page.PageData;
import com.ykt.common.utils.page.PageParam;
import com.ykt.model.Order;
import com.ykt.model.OrderItem;
import com.ykt.vo.StatisticsGoodsVo;
import com.ykt.vo.StatisticsOrderVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 订单服务
 *
 * @author long.hua
 * @version 1.0.0
 * @since 2016-02-15 23:50
 */
public class OrderService {
    private final static Logger LOGGER = LoggerFactory.getLogger(OrderService.class);

    private Order orderDao = Order.dao;
    private OrderItem orderItemDao = OrderItem.dao;
    private OrderCache orderCache = Enhancer.enhance(OrderCache.class.getName(), OrderCache.class);


    public Order findById(int orderId) {
        return orderDao.findById(orderId);
    }

    public List<OrderItem> findOrderItems(int orderId) {
        return orderItemDao.findByOrderId(orderId);
    }

    public PageData<Order> pageFindByShopIdAndStatus(PageParam<Map<String, Object>> param) {
        int shopId = UB.i(param.getP().get(Order.shop_id), -1);
        if (shopId == -1) {
            LOGGER.warn("参数shop id为空!");
            return null;
        }

        return orderDao.pageFindByShopIdAndStatus(param);
    }

    public List<Order> findByMerchantUnconfirmed(int shopId) {
        if (shopId < 0) {
            LOGGER.warn("参数Shop ID为空!");
            return null;
        }

        // 查询上次查询时间
        Date lastFindTime = orderCache.getLastFindTime(shopId);
        orderCache.setLastFindTime(shopId, new Date());
        lastFindTime = (lastFindTime == null) ? DateUtil.getYMD(2016, 1, 1) :lastFindTime;

        return orderDao.findByMerchantUnconfirmed(shopId, lastFindTime);
    }

    @Before(Tx.class)
    public void updateStatus(int orderId, String status) {
        orderDao.set(Order.id, orderId);
        orderDao.set(Order.status, status);
        orderDao.set(Order.updated_time, new Date());
        orderDao.update();
    }

    public StatisticsOrderVo statisticsOrder(Map<String, Object> params) {
        LOGGER.info("Input parameter is {}", params);
        int pageNo = 1;
        int pageSize = ValueConstants.PAGE_SIZE_100;

        StatisticsOrderVo statisticsVo = new StatisticsOrderVo();
        Map<Integer, StatisticsGoodsVo> goodsMap = new HashMap<>();

        Set<Integer> orderIds = new HashSet<>();
        double amount = 0;
        double payAmount = 0;
        int orderCount = 0;
        
        int undeliveryOrderCount = 0;//待发货订单数
        int unconfirmedOrderCount = 0;//待确认订单数

        PageParam<Map<String, Object>> pageParam = new PageParam<>(pageNo, pageSize, params);
        PageData<Order> pd = orderDao.pageFindOrderAndItemByShopIdAndStatus(pageParam);
        while (pd != null && Colls.notEmpty(pd.getPageData())) {

            for (Order order : pd.getPageData()) {
                Integer id = order.get(OrderItem.order_id);
                if (!orderIds.contains(id)) {
                    orderIds.add(id);
                    amount += ModelUtil.d(order, Order.amount);
                    payAmount += ModelUtil.d(order, Order.pay_amount);
                    
                    orderCount++;//总订单数
                    if(order.getStr(Order.status).equals("MERCHANT_UNDELIVERY")){
                    	undeliveryOrderCount++;
                    }
                    if(order.getStr(Order.status).equals("MERCHANT_UNCONFIRMED")){
                    	unconfirmedOrderCount++;
                    }
                }
                if(order.getStr(Order.status).equals("MERCHANT_UNDELIVERY")){//只统计待发货的商品清单
                	Integer goodsId = order.get(OrderItem.goods_id);
                	double goodsPCS = ModelUtil.d(order, OrderItem.goods_pcs);
                	int goodsCount = order.get(OrderItem.goods_count);

                	if (!goodsMap.containsKey(goodsId)) {
                		goodsMap.put(goodsId, new StatisticsGoodsVo());
                	}

                	int goodsNum = goodsMap.get(goodsId).getGoodsNum();
                	goodsMap.get(goodsId).setGoodsNum(goodsNum + goodsCount);
                	double goodsJinCount = UB.d(goodsMap.get(goodsId).getGoodsJinCount(), 0);
                	goodsMap.get(goodsId).setGoodsJinCount(goodsJinCount + goodsCount * goodsPCS);
                	goodsMap.get(goodsId).setGoodsName(order.getStr(OrderItem.goods_name));
                	goodsMap.get(goodsId).setGoodsUnit(order.getStr(OrderItem.goods_unit));
                	goodsMap.get(goodsId).setGoodsNo(order.getStr(OrderItem.goods_no));
                }
            }

            statisticsVo.setShopId(UB.i(params.get("shopId"), 0));
            statisticsVo.setAmount((Double.valueOf(NumUtil.format(amount))));
            statisticsVo.setOrderCount(orderCount);
            statisticsVo.setUndeliveryOrderCount(undeliveryOrderCount);
            statisticsVo.setUnconfirmedOrderCount(unconfirmedOrderCount);
            statisticsVo.setPayAmount((Double.valueOf(NumUtil.format(payAmount))));
            statisticsVo.setGoodsVos(new ArrayList<>(goodsMap.values()));

            pageParam.setOffset(PageData.calcOffset(++pageNo, pageSize));
            pd = orderDao.pageFindOrderAndItemByShopIdAndStatus(pageParam);
        }

        return statisticsVo;
    }
}
